Amazon FSx for Windows File Server の Active Directory 検証ツールを試してみた
しばたです。
Amazon FSx for Windows File Server(以後 FSx for Windows)では認証基盤としてオンプレ環境などにあるActive Directoryを直接使用することができます。
FSx for WindowsでセルフマネージドなActive Directoryを利用するには所定の前提条件を満たしておく必要があり、前提条件を満たしているか確認するための検証ツールも提供されています。
本記事ではこの検証ツールの概要と検証内容について解説します。
事前準備
この検証ツールはPowerShellモジュールとして提供されています。
FSx for Windowsを展開するサブネットに検証用EC2を用意し、EC2内部からPowerShellモジュールのコマンドを実行することで検証を行います。
ドキュメントでは検証ツールを実行するにあたり以下の事前準備が必要とされていますが、検証内容によっては不要なものもありますので環境に応じて必要な分を準備しておけば良いでしょう。
- (必須) EC2インスタンスはWindows Serverであること
- 検証ツールでは内部でAWS Tools for PowerShellの機能を使う
- 検証ツールでは内部でAcitveDirectoryモジュールを使うためPowerShell on Linuxは不可
- OSバージョンに対する要件は明記されていない
- (ほぼ必須) EC2インスタンスに
ec2:DescribeSubnets
,ec2:DescribeVpcs
の権限を持つIAMロールをアタッチする- ドキュメントでは
AmazonEC2ReadOnlyAccess
ロールを与えておく手順となっている - 検証ツールでポートスキャンするだけなら不要。それ以外の検証では必須
- ドキュメントでは
- (ほぼ必須) EC2インスタンスが対象Active Directoryドメインに参加していること
- ドキュメントでは対象ドメインへの参加を要求されているが、不参加でもなんとかなる
- 検証ツールでポートスキャンするだけならドメインへの参加は不要
特に対象ドメインへの参加については、そもそもドメインに参加できるなら検証は半分くらい終わっているわけで個人的には微妙な要件だと感じています。
私が試した限りではEC2が参照するDNSサーバーを当該ドメインコントローラーに向けておけばドメイン不参加の状態でも検証を実行することができましたので、まずはドメイン不参加の状態で検証を試し必要が出た時点でドメイン参加するのが良いのではないかと思います。
(なお、DNSサーバーの設定を変えないと後述の検証Test 7
でエラーとなる)
EC2の準備
本記事では具体的なEC2インスタンスの構築手順は割愛します。
CLI、マネジメントコンソール、好きな方法で用意してください。
前述の通りOSバージョンに対する要件は明記されていないのですが、最新のWindows Server 2019にしておけば問題ないでしょう。
IAMロールについても適宜設定してください。
本記事ではAmazonEC2ReadOnlyAccess
権限を持つロールのCloudFormation Templateを一例として紹介しておきます。
AWSTemplateFormatVersion: 2010-09-09
Parameters:
RoleName:
Description: "Input role name."
Type: String
Default: "EC2RoleforFSxADValidation"
Resources:
# IAM Role
FSxRole:
Type: AWS::IAM::Role
Properties:
RoleName:
Fn::Sub: "${RoleName}"
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Principal:
Service:
- "ec2.amazonaws.com"
Action:
- "sts:AssumeRole"
Path: "/"
ManagedPolicyArns:
- "arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess"
# Instance Profile
FSxRoleInstanceProfile:
Type: "AWS::IAM::InstanceProfile"
Properties:
InstanceProfileName:
Fn::Sub: "${RoleName}"
Path: "/"
Roles:
- Ref: FSxRole
検証ツールのインストール
EC2を構築した後は検証ツールのインストールを行います。
前述の通り検証ツールでは内部でAcitveDirectoryモジュールを使用するため、Install-WindowsFeature
を使ってモジュールを含むリモート管理ツールをインストールします。
# (要管理者権限) Active Directoryリモート管理ツールをインストール
Install-WindowsFeature RSAT-AD-PowerShell
次に、管理ツールはAWSのサイト上でZipファイル形式で提供されているので任意のフォルダにダウンロードして展開します。
以下の例ではC:\fsx
というフォルダを用意しそこにツールを展開しています。
# 今回は C:\fsx というディレクトリを作りそこで諸々の作業を実施
mkdir C:\fsx
cd C:\fsx\
# FSx 検証ツールのダウンロードと解凍
Invoke-WebRequest "https://docs.aws.amazon.com/fsx/latest/WindowsGuide/samples/AmazonFSxADValidation.zip" -OutFile "AmazonFSxADValidation.zip"
Expand-Archive -Path "AmazonFSxADValidation.zip"
これでC:\fsx\AmazonFSxADValidation
に検証ツールが展開され利用可能な状態になります。
以上で事前準備は完了です。
試してみた
ここからは検証ツールを実際に試していきます。
はじめに前項で展開したモジュールをImport-Module
で明示的にインポートします。
# 前項で展開したモジュールをインポートする
cd C:\fsx\
Import-Module .\AmazonFSxADValidation
警告: 既定のドライブを初期化中にエラーが発生しました: 'Active Directory Web
サービスが実行されている状態で既定のサーバーを検索することはできません。'。
環境によっては上記の警告が出ることもありますが、これは無視して構いません。
Get-Command
を使い検証ツールで公開されているコマンドを調べると以下の3コマンド用意されていることがわかります。
Get-Command -Module AmazonFSxADValidation
CommandType Name Version Source
----------- ---- ------- ------
Function Test-FSxADConfiguration 1.0 AmazonFSxADValidation
Function Test-FSxADControllerConnection 1.0 AmazonFSxADValidation
Function Test-FSxADDnsConnection 1.0 AmazonFSxADValidation
1. ポートスキャン (Test-FSxADDnsConnection, Test-FSxADControllerConnection)
公開されているコマンドのうちTest-FSxADDnsConnection
とTest-FSxADControllerConnection
についてはポートスキャンを行うものになります。
これらについてはドメイン不参加、IAMロール未設定の状態でも実行可能です。
Test-FSxADDnsConnection
はDNSサーバーに対するポートスキャンを行い、TCP 53、UDP 53番ポートへの疎通をチェックします。
# DNSサーバーへのポートスキャンは Test-FSxADDnsConnection
Test-FSxADDnsConnection -ADDnsIp <対象サーバーのIP> -OutVariable result
# 実行結果の詳細は以下
$result.Success
$result.TcpDetails
$result.UdpDetails
Test-FSxADControllerConnection
はドメインコントローラーに対するポートスキャンを行い、TCP 88,135,389,445,464,636,3268,9389、UDP 88,123,389,464番ポートへの疎通をチェックします。
# ドメインコントローラーへのポートスキャンは Test-FSxADControllerConnection
Test-FSxADControllerConnection -ADControllerIp <対象サーバーのIP> -OutVariable result
# 実行結果の詳細は以下
$result.Success
$result.TcpDetails
$result.UdpDetails
2のコマンドで微妙にパラメーター名が異なりますが細かい説明無くお使いいただけるかと思います。
スキャンした全体の結果についてはSuccess
プロパティから取得可能で、プロトコルごとの結果はそれぞれTcpDetails
、UdpDetails
プロパティから取得できます。
ポート毎のスキャン結果についてはPortQryの内容に準じ、
Listening
: ポートが解放されているListening or Filtered
: ポートが解放されているかブロックされているか不明- その他 : エラーの場合
を返します。
【注意】UDPのスキャン結果について
ここで補足なのですが、残念ながらこの検証ツールではUDPのポートスキャンの実装が悪く常に「Listening or Filtered
」を返してしまいます。
(TCPのポートスキャンは問題ありません)
UDPはTCPの様に"わかりやすい"ハンドシェイクが無いため元来ポートスキャンが面倒な事情があります。
UDPでは正しいパケットを送り付けないとポートが空いていても応答を返さないものがあり、検証ツールで検査するポートは全てその類です。
この検証ツールでは以下の様にシンプルに?(0x3f)
を送り付ける実装となっているためどのプロトコルも応答を返してくれません。
#
# UDPのポートスキャン実装から一部抜粋
#
$Result = "Unknown"
$UdpClient = New-Object System.Net.Sockets.UdpClient
$UdpClient.Client.ReceiveTimeout = $Timeout
Try {
$Connect = $UdpClient.Connect($Server, $Port)
$Acsii = New-Object System.Text.ASCIIEncoding
$Bytes = $Acsii.GetBytes("?");
[void]$UdpClient.Send($Bytes, $Bytes.length)
$RemoteEndpoint = New-Object System.Net.IpEndpoint([System.Net.IpAddress]::Any, 0)
$ReceiveBytes = $UdpClient.Receive([ref\]$RemoteEndpoint)
[string]$ReturnData = $Acsii.GetString($ReceiveBytes)
If ($ReturnData) {
$Result = "Listening"
}
} Catch [System.Net.Sockets.SocketException] {
$SocketException = $_.Exception
# https://msdn.microsoft.com/en-us/library/ms740668.aspx
If (($SocketException.ErrorCode -eq 10054) -or ($SocketException.ErrorCode -eq 10061)) {
$Result = "SocketError $SocketException.ErrorCode"
} Else {
# Treat everything other than explicitly refused to be success for UDP.
$Result = "Listening or Filtered"
}
} Finally {
$UdpClient.Dispose()
}
UDPのポートスキャンを正確に行いたい場合はこのツールではなく、PortQryやNmapを使うと良いでしょう。
とはいえPortQryやNmapでも限界はあり、私が調べた限り以下の対応状況でした。
ポート | プロトコル | PortQry 2.0 | Nmap 7.91 (デフォルト設定) |
---|---|---|---|
UDP 53 | DNS | 〇:正しい結果を返す | 〇:正しい結果を返す |
UDP 88 | Kerberos認証 | ×:非対応 | ×:非対応 (ただしkrb5-enum-usersスクリプトによる調査は可) |
UDP 123 | NTP | ×:非対応 | 〇:正しい結果を返す |
UDP 389 | LDAP | 〇:正しい結果と詳細情報を返す | ×:非対応 (ただしldap-searchスクリプトによる調査は可) |
UDP 464 | Kerberosパスワード変更(kpasswd5) | ×:非対応 | ×:非対応 |
2. Active Directoryの検証 (Test-FSxADConfiguration)
Active Directoryの検証にはTest-FSxADConfiguration
コマンドを使います。
このコマンドの実行には
- EC2に対するIAMロールの設定は必須
- 最低限EC2のDNS設定を切り替えておく事(最悪ドメインに参加させる)
の前提条件が必要となります。
このコマンドは以下の様な感じで多数の引数を取ります。
各パラメーターの詳細はモジュールに付属しているREADMEを一読いただきたいですが、以下の例を環境に合わせて改変して実行する形でも良いかと思います。
# FSx管理者ユーザーの認証情報を指定 (ユーザー指定はSPNでなく単純なユーザー名にする必要あり)
$password = ConvertTo-SecureString '<平文のパスワード>' -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential ('fsxadmin', $password)
# 各種パラメーター設定+コマンド実行
$FSxADValidationArgs = @{
# 対象ドメインのDNS名を指定
DomainDNSRoot = 'corp.contoso.com'
# 対象ドメインのDNSサーバーのIPアドレスを指定
DnsIpAddresses = @('xxx.xxx.xxx.xxx', 'yyy.yyy.yyy.yyy')
# FSx管理用OUを識別名で指定
OrganizationalUnit = 'OU=FSxOU,DC=corp,DC=contoso,DC=com'
# FSx管理者の所属するグループ名を指定
AdminGroup = 'FSxGroup'
# FSxを配備するサブネットのサブネットIDを指定
SubnetIds = @('subnet-1234567890', 'subnet-9876543210')
Credential = $credential
}
$result = Test-FSxADConfiguration @FSxADValidationArgs
コマンドを実行すると以下の様な感じで「対象ドメインにテスト用のオブジェクトを作成するが良いか?」と聞かれますので問題なければ「y」を入力し検証を続行してください。
Testing service account permissions is not currently enabled. If enabled, script will create test Active Directory computer objects in the organizational unit. This will be cleaned up by the script unless delete permissions are not properly configured on the provided service account in which case manual cleanup may be necessary. Do you want to enable testing? [y/n]:
テスト用オブジェクトはFSx管理用OUに作成され検証が終わると同時に削除されます。
私が調べた限りではFSx管理用OU以外の場所に対する更新はありませんでしたので、あまり気にせずテストを続行して構わないと思います。
検証は全部で16個のテストから構成されており、途中でエラーがでると以降のテストは全てスキップされます。
全てテストが無事完了すると以下の様な感じになります。
テスト結果は$result
変数に格納されますので、こちらの各種プロパティから詳細情報を取得できます。
Test-FSxADConfiguration の検証一覧
Test-FSxADConfiguration
で行われる16個のテストの一覧は以下となります。
Test 1 - Validate EC2 Subnets
EC2にインストール済みのAWS Tools for PowerShell(Get-Ec2Subnet
, Get-Ec2Vpc
)を使い、指定のサブネット群がすべて同一のVPCにあるか、別々のAZに分かれているかをチェックします。
テストに合格するとVPC、サブネット情報が戻り値に追加されます。
当然ですが、EC2にIAMロールが割り当てられていないとこのテストには合格しません。
Test 2 - Validate connectivity with DNS Servers
指定のDNSサーバーに対して特定のSRVレコード(_ldap._tcp.dc._msdcs.<ドメイン名>
等)の存在チェックを行い、DNSサーバーに対する疎通を確認します。
テストに合格するとドメインコントローラの情報が戻り値に追加されます。
Test 3 - Validate FSx service user credentials
指定されたFSx管理ユーザーがドメインに存在するかチェックします。同時にドメイン情報の取得も行います。
テストに合格するとドメイン情報が戻り値に追加されます。
FSx管理ユーザーの認証情報に誤りがある場合はここでエラーになります。
Test 4 - Validate domain properties
Test 3の結果を元に
- ドメインの機能レベルが「Windows Server 2008 R2以降」であること
- シングルラベルドメイン(SLD)でないこと (FSxではSLDは非サポート)
を確認します。
Test 5 - Validate organizational unit
指定のFSx管理用OUがドメインに存在するかチェックします。
テストに合格するとOU情報が戻り値に追加されます。
Test 6 - Validate Admin Group
指定のFSx管理ユーザー用グループがドメインに存在するかチェックします。
テストに合格するとグループ情報が戻り値に追加されます。
Test 7 - Validate that provided EC2 Subnets belong to a single AD Site
指定のサブネットがどのActive Directoryサイトに存在するか、複数のサイトにまたがる様なアドレスになっていないかをチェックします。
テストに合格するとサイト情報が戻り値に追加されます。
Test 8 - Looking up DNS entries for domain controllers in site <サイト名>
指定のDNSサーバーに対して特定のSRVレコード(_ldap._tcp.<サイト名>._sites.dc._msdcs.<ドメイン名>
等)の存在チェックを行い、サイトに関連するDNSレコードが正しく取得できるかチェックします。
Test 9 - Validate connectivity with at least one AD Domain Controller in AD site <サイト名>
これまでのテストで取得した情報を踏まえてドメインコントローラーへの疎通チェックを行います。
内部でTest-FSxADControllerConnection
を使用しているため、残念ながらUDPのチェックは当てになりません。
Test 10 - Validate 'Create Computer Objects' permission
指定のFSx管理用OUに対しコンピューターオブジェクトが作成可能かチェックします。
このテストではamznfsxtestXXXX (XXXXはランダムな16進数)
というオブジェクトを実際に作成します。
Test 11 - Validate 'Validated write to DNS host name' permission
FSx管理者ユーザーがコンピューターオブジェクトに対するDNS名の更新権限を持っているかチェックします。
Test 10で作成したテスト用コンピューターオブジェクトを更新すること(Set-ADComputer
)で権限を確認しています。
Test 12 - Validate 'Validated write to service principal name' permission
FSx管理者ユーザーがコンピューターオブジェクトに対するサービスプリンシパル名(SPN)の更新権限を持っているかチェックします。
Test 10で作成したテスト用コンピューターオブジェクトを更新すること(Set-ADComputer
)で権限を確認しています。
Test 13 - Validate 'Reset Password' permission
FSx管理者ユーザーがパスワードリセットの権限を持っているかチェックします。
Test 10で作成したテスト用コンピューターオブジェクトにランダムなパスワードを設定すること(Set-ADAccountPassword
)で権限を確認しています。
Test 14 - Validate 'This Organization' list children permission
指定のFSx管理用OUの子要素に対する参照権限があるかチェックします。
Test 10で作成したテスト用コンピューターオブジェクトの認証情報を使い自分自身を参照(Get-ADComputer
)可能か確認しています。
Test 15 - Validate 'Read and write Account Restrictions' permission
FSx管理者ユーザーがコンピューターオブジェクトに対するアカウント制限の更新権限を持っているかチェックします。
Test 10で作成したテスト用コンピューターオブジェクトの属性を更新すること(Set-ADAccountControl -PasswordNotRequired $False
)で権限を確認しています。
Test 16 - Validate 'Delete Computer Objects' permission
FSx管理者ユーザーがコンピューターオブジェクトに対する削除権限を持っているかチェックします。
Test 10で作成したテスト用コンピューターオブジェクトを削除することで確認しています。
これですべてのテストが完了です。
最後に
以上となります。
導入までのハードルが若干高いツールですが詳細な検証を行っていると感じました。
ポートスキャンについてはちょっと残念なところがありましたが他ツールを併用すれば問題にはならないでしょう。
FSx for Windowsの導入に際し必要に応じて使ってみてください。